import javalang

# Java 代码示例
java_code = """
package com.pingpongx.business.payout.api.service;

import com.pingpongx.business.common.dto.OrderDTO;
import com.pingpongx.business.payout.api.dto.request.FileOrderPayRequest;
import com.pingpongx.business.payout.api.dto.request.MassOrderPayRequest;
import com.pingpongx.business.payout.api.dto.request.OrderPayRequest;
import com.pingpongx.business.payout.api.dto.request.TripartiteOrderPayRequest;
import com.pingpongx.business.payout.api.dto.request.emailPay.MassEmailOrderPayRequest;
import com.pingpongx.business.payout.api.dto.response.EmailPay.FileEmailPayResponse;
import com.pingpongx.business.payout.api.dto.response.FileOrderPayResponse;
import com.pingpongx.business.payout.api.dto.response.MassOrderPayResponse;
import com.pingpongx.business.payout.api.dto.response.tripartite.TripartiteOrderPayResponse;

/**
 * PayoutService
 */
public interface PayoutService {

    String version = "1.0";

    /**
     * 单笔下单场景(全业务)
     * /api/front/payout/createTransferScaOrder
     * @param request
     * @return
     */
    OrderDTO createOrder(OrderPayRequest request);
    OrderDTO createVatOrder(OrderPayRequest request);
    OrderDTO createWithdrawOrder(OrderPayRequest request);
    OrderDTO createSupplierOrder(OrderPayRequest request);
    OrderDTO createExchangeOrder(OrderPayRequest request);

    /**
     * 创建需要安全验证【短信验证】的订单(全业务)
     * @param request
     * @return
     */
    OrderDTO createScaOrder(OrderPayRequest request);
    OrderDTO createSupplierScaOrder(OrderPayRequest request);
    OrderDTO createWithdrawScaOrder(OrderPayRequest request);
    OrderDTO createVatScaOrder(OrderPayRequest request);

    /**
     * 接入三方授权创建出金单
     * @param request
     * @return
     */
    TripartiteOrderPayResponse createThirdPartOrder(TripartiteOrderPayRequest request);


    /**
     * 创建邮件方式订单
     * @param request
     * @return
     */
    OrderDTO createEmailPayOrder(OrderPayRequest request);

    /**
     * 创建能者供应商订单
     */
    OrderDTO createCapSupplierOrder(OrderPayRequest request);

    /**
     * 创建能者转账订单
     */
    OrderDTO createCapTransferOrder(OrderPayRequest request);


    /**
     * 检查订单金额是否受限
     */
    boolean checkOrderAmountLimit(OrderPayRequest request);

    /**
     * 创建requestPay订单
     * @param request
     * @return
     */
    OrderDTO createRequestPayOrder(OrderPayRequest request);

    /**
     * 文件形式批量操作订单
     * @param request
     * @return
     */
    FileOrderPayResponse createFileOrder(FileOrderPayRequest request);

    /**
     * 批量付款Group模式
     * @param request
     * @return
     */
    MassOrderPayResponse createMassOrder(MassOrderPayRequest request);

    /**
     * 批量EmailPay模式
     * @param request 请求数据
     * @return
     */
    FileEmailPayResponse createEmailFileOrder(MassEmailOrderPayRequest request);

    /**
     * 冻结订单(收银台模式下单分两步。1.预下单(createOrder创建订单)，2.冻结订单)
     * @param clientId
     * @param orderId
     * @return
     */
    OrderDTO frozenOrder(String clientId,String orderId);

    /**
     * 主动取消订单
     */
    void cancelOrder(String clientId, String orderId);

    /**
     * 订单过期
     * @param clientId
     * @param orderId
     */
    void expiredOrder(String clientId, String orderId);

    /**
     * 订单能否取消
     */
    boolean orderCanCancel(String clientId, String orderId);

    /**
     * 更换订单BA(boss需求)(clientId,orderId,bizId)
     * @param orderDTO
     */
    void changeOrderBA(OrderDTO orderDTO);

    void declineOnlineOrders(String clientId);

    /**
     * 待激活订单激活（目前只有us区）
     * @param clientId
     */
    void activeOrders(String clientId);

    /**
     * 更新用户订单中用户level信息 （目前只有us区）
     * @param clientId
     */
    @Deprecated
    void updateOrdersUserLevelByKycPass(String clientId);

    /**
     * 更新订单第三方失败原因
     * @param clientId
     * @param orderId
     * @param failReason
     */
    void updateOrderTripartiteFailReason(String clientId, String orderId, String failReason);
}

"""

# # 解析 Java 代码
# tree = javalang.parse.parse(java_code)
# # print(tree)
# for path, node in tree:
#     print("-" * 100)
#     print(path)
#     print(node)
#     break


class JavaAnalyzer:
    def __init__(self, filepath, source_code):
        self.filepath = filepath
        self.source_code = source_code
        self.source_lines = source_code.split("\n")
        self.nodes = []
        self.package_name = ""
        self.imports = []
        self.inheritance_info = []

    def _extract_code_block(self, start_line, end_line):
        """提取指定行范围的代码"""
        if start_line <= 0 or start_line > len(self.source_lines):
            return ""

        start_idx = start_line - 1
        end_idx = min(end_line, len(self.source_lines))

        return "\n".join(self.source_lines[start_idx:end_idx])

    def _get_end_line_number(self, node, start_line):
        """估算节点的结束行号"""
        try:
            end_line = start_line
            if hasattr(node, "body") and node.body:
                max_child_line = start_line
                for child in node.body:
                    child_line = self._get_line_number(child)
                    if child_line > max_child_line:
                        max_child_line = child_line
                end_line = max_child_line + 5
            return min(end_line, len(self.source_lines))
        except:
            return start_line + 10

    def _get_line_number(self, node):
        """获取节点的行号"""
        try:
            if hasattr(node, "position") and node.position:
                return node.position.line
        except:
            pass
        return 1

    def _extract_method_calls_from_node(self, node):
        """从节点中提取方法调用"""
        calls = []

        def collect_calls(n):
            if isinstance(n, javalang.tree.MethodInvocation):
                calls.append(n.member)
            elif isinstance(n, javalang.tree.ClassCreator):
                # 构造函数调用
                if hasattr(n, "type") and hasattr(n.type, "name"):
                    calls.append(n.type.name)

            # 递归遍历子节点
            if hasattr(n, "children"):
                for child in n.children:
                    if child:
                        if isinstance(child, list):
                            for item in child:
                                if item:
                                    collect_calls(item)
                        else:
                            collect_calls(child)

        try:
            collect_calls(node)
        except Exception as e:
            print(f"Error extracting method calls: {e}")

        return calls

    def _visit_method(self, node, parent_class):
        """访问方法声明"""
        method_name = node.name
        full_method_name = f"{parent_class}.{method_name}"
        if full_method_name == "PayoutService.declineOnlineOrders":
            print(1)

        start_line = self._get_line_number(node)
        end_line = self._get_end_line_number(node, start_line)
        code_block = self._extract_code_block(start_line, end_line)

        # 获取参数信息
        parameters = []
        if hasattr(node, "parameters") and node.parameters:
            for param in node.parameters:
                parameters.append(
                    {
                        "name": param.name,
                        "type": str(param.type) if param.type else "unknown",
                    }
                )

        # 提取方法调用
        method_calls = self._extract_method_calls_from_node(node)

        method_node = {
            "name": full_method_name,
            "type": "",
            "code": code_block,
            "start_line": start_line,
            "end_line": end_line,
            "parameters": parameters,
            "return_type": str(node.return_type) if node.return_type else "void",
            "modifiers": [str(mod) for mod in node.modifiers] if node.modifiers else [],
            "method_calls": method_calls,
        }
        self.nodes.append(method_node)

    def _visit_interface(self, node):
        """访问接口声明"""
        interface_name = node.name
        if interface_name == "declineOnlineOrders":
            print(1)

        start_line = self._get_line_number(node)
        end_line = self._get_end_line_number(node, start_line)
        code_block = self._extract_code_block(start_line, end_line)

        # 接口可以extends其他接口
        extends_interfaces = []
        if hasattr(node, "extends") and node.extends:
            extends_interfaces = [ext.name for ext in node.extends]

        interface_node = {
            "name": interface_name,
            "type": "class",
            "code": code_block,
            "start_line": start_line,
            "end_line": end_line,
            "extends": extends_interfaces,
            "is_interface": True,
            "modifiers": [str(mod) for mod in node.modifiers] if node.modifiers else [],
        }
        self.nodes.append(interface_node)

        # 记录继承信息
        for parent_interface in extends_interfaces:
            self.inheritance_info.append((interface_name, parent_interface, "extends"))

        # 处理接口方法
        if hasattr(node, "body"):
            for member in node.body:
                if isinstance(member, javalang.tree.MethodDeclaration):
                    self._visit_method(member, interface_name)

    def _visit_type(self, node):
        """访问类型声明节点"""
        if isinstance(node, javalang.tree.ClassDeclaration):
            self._visit_class(node)
        elif isinstance(node, javalang.tree.InterfaceDeclaration):
            self._visit_interface(node)
        elif isinstance(node, javalang.tree.EnumDeclaration):
            self._visit_enum(node)

    def analyze(self, tree):
        """分析Java语法树并提取节点"""
        if hasattr(tree, "package") and tree.package:
            self.package_name = tree.package.name

        # 提取import信息
        if hasattr(tree, "imports"):
            for import_decl in tree.imports:
                import_info = {
                    "path": import_decl.path,
                    "static": getattr(import_decl, "static", False),
                    "wildcard": getattr(import_decl, "wildcard", False),
                }
                self.imports.append(import_info)
                print(f"Found import: {import_info}")  # 调试信息

        # 分析类型声明
        if hasattr(tree, "types"):
            for type_decl in tree.types:
                self._visit_type(type_decl)

        return self.nodes


tree = javalang.parse.parse(java_code)
analyzer = JavaAnalyzer("filepath", java_code)
nodes = analyzer.analyze(tree)
print(nodes, analyzer.imports, analyzer.inheritance_info)
